package org.example;


import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.example.entity.menu.AllMenu;
import org.example.entity.menu.Menu;


import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HttpApplication {
    //递归爬取菜单写入excel文件
    public static void main(String[] args) {
        Workbook workbook= new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("Sheet1");

        ObjectMapper objectMapper = new ObjectMapper();
        String url = "https://wljy.whut.edu.cn/navMenu/initNavTree.ajax";
        // POST 请求示例，带请求头
        try {
            Integer rowIndex = 0;
            Integer colIndex = 0;

            List<AllMenu> result = getResult(objectMapper, url, "", AllMenu.class);
            AllMenu allMenu = result.get(0);
            List<Menu> children = allMenu.getChildren();
            digui(children,url,objectMapper,"SUPPER_COLUMN",sheet,rowIndex,colIndex);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

        // 输出到文件
        try (FileOutputStream fos = new FileOutputStream("C:\\Users\\QCY\\Desktop\\example_output.xlsx")) {
            workbook.write(fos);
            System.out.println("Excel 文件写入完成！");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    public static void digui(List<Menu> menus, String url, ObjectMapper objectMapper, String pId, Sheet sheet, int rowIndex, int colIndex) {
        for (Menu menu : menus) {
            rowIndex = writeToExcel(sheet, menu, rowIndex, colIndex, url, objectMapper); // 动态处理每个菜单
        }
    }
    public static int writeToExcel(Sheet sheet, Menu menu, int rowIndex, int colIndex, String url, ObjectMapper objectMapper) {
        // 动态获取当前菜单的子菜单数据
        List<Menu> children = new ArrayList<>();
        if (menu.getIsParent()) {
            try {
                children = getResult(objectMapper, url, "id=" + menu.getId() + "&pId=" + menu.getId() + "&value=", Menu.class);
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("获取子菜单失败: " + menu.getName());
            }
        }

        // 计算当前菜单需要占据的行数
        int rowsToMerge = getTotalRows(menu, children);

        // 确保当前行存在
        Row row = sheet.getRow(rowIndex);
        if (row == null) {
            row = sheet.createRow(rowIndex);
        }

        // 写入当前菜单的名称
        row.createCell(colIndex).setCellValue(menu.getName());

        // 如果有子菜单，合并当前单元格并递归写入子菜单
        if (!children.isEmpty()) {
            // 合并单元格
            if (rowsToMerge > 1) {
                sheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex + rowsToMerge - 1, colIndex, colIndex));
            }

            // 递归写入子菜单
            int nextRowIndex = rowIndex;
            for (Menu child : children) {
                nextRowIndex = writeToExcel(sheet, child, nextRowIndex, colIndex + 1, url, objectMapper);
            }
            return nextRowIndex; // 返回当前处理后的最后一行索引
        } else {
            // 如果没有子菜单，直接返回下一行
            return rowIndex + 1;
        }
    }

    private static int getTotalRows(Menu menu, List<Menu> children) {
        if (children.isEmpty()) {
            return 1; // 没有子菜单，占据一行
        }

        // 如果有子菜单，递归计算总行数
        int totalRows = 0;
        for (Menu child : children) {
            try {
                List<Menu> childChildren = getResult(new ObjectMapper(), "https://wljy.whut.edu.cn/navMenu/initNavTree.ajax",
                        "id=" + child.getId() + "&pId=" + menu.getId() + "&value=", Menu.class);
                totalRows += getTotalRows(child, childChildren);
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("获取子菜单失败: " + child.getName());
            }
        }
        return totalRows;
    }










    private static <T> List<T> getResult(ObjectMapper objectMapper, String url, String canshu, Class<T> tClass) throws Exception {
        // 自定义请求头
        Map<String, String> headers1 = new HashMap<>();
        headers1.put("Accept", "application/json, text/javascript, */*; q=0.01");
        headers1.put("Accept-Encoding", "gzip, deflate, br, zstd");
        headers1.put("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6");
        headers1.put("Cache-Control", "no-cache");
        headers1.put("Connection", "keep-alive");
        headers1.put("Content-Type", "application/x-www-form-urlencoded");
        headers1.put("Cookie", "USERLOGIN_USERNAME_COOKIE=wukaikui; USERLOGIN_USERPWD_COOKIE=IyQlcjY3OFkt; USERLOGIN_USERORG_COOKIE=00; USERLOGIN_USERLANG_COOKIE=\"\"; JSESSIONID=842C7AFBA69F8580DB038DDE77A1E84A");
        headers1.put("Host", "wljy.whut.edu.cn");
        headers1.put("Origin", "https://wljy.whut.edu.cn");
        headers1.put("Pragma", "no-cache");
        headers1.put("Referer", "https://wljy.whut.edu.cn/permissionManager.action?moduleId=PERMISION");
        headers1.put("Sec-Fetch-Dest", "empty");
        headers1.put("Sec-Fetch-Mode", "cors");
        headers1.put("Sec-Fetch-Site", "same-origin");
        headers1.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0");
        headers1.put("X-Requested-With", "XMLHttpRequest");
        headers1.put("sec-ch-ua", "\"Microsoft Edge\";v=\"131\", \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"");
        headers1.put("sec-ch-ua-mobile", "?0");
        headers1.put("sec-ch-ua-platform", "\"Windows\"");

        // 自定义请求体
        String requestBody1 = canshu;

        // 发送 POST 请求
        String response1 = sendPostRequest(url, headers1, requestBody1);

        // 构造目标类型的泛型信息
        JavaType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, tClass);

        // 使用 ObjectMapper 反序列化为目标对象
        List<T> object = objectMapper.readValue(response1, listType);

        return object;
    }


    /**
     * 发送 POST 请求的方法
     * @param urlString 请求的 URL
     * @param headers   自定义请求头
     * @param requestBody 请求体
     * @return 响应内容
     * @throws Exception
     */
    public static String sendPostRequest(String urlString, Map<String, String> headers, String requestBody) throws Exception {
        // 创建 URL 对象
        URL url = new URL(urlString);

        // 打开连接
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        // 设置请求方法为 POST
        connection.setRequestMethod("POST");



        // 设置请求头
        for (Map.Entry<String, String> header : headers.entrySet()) {
            connection.setRequestProperty(header.getKey(), header.getValue());
        }

        // 启用写入请求体
        connection.setDoOutput(true);

        // 写入请求体数据
        try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) {
            outputStream.writeBytes(requestBody);
            outputStream.flush();
        }

        // 获取响应代码
        int responseCode = connection.getResponseCode();
//        System.out.println("响应代码: " + responseCode);

        // 读取响应头
//        System.out.println("响应头信息：");
//        Map<String, List<String>> responseHeaders = connection.getHeaderFields();
//        for (Map.Entry<String, List<String>> entry : responseHeaders.entrySet()) {
//            System.out.println(entry.getKey() + ": " + entry.getValue());
//        }

        // 读取响应数据
        BufferedReader reader;
        if (responseCode >= 200 && responseCode < 300) {
            // 正常响应
            reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        } else {
            // 错误响应
            reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
        }

        StringBuilder response = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            response.append(line);
        }
        reader.close();

        // 关闭连接
        connection.disconnect();

        // 返回响应数据
        return response.toString();
    }








}
